//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension GreengrassV2 {
    // MARK: Enums

    public enum CloudComponentState: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case deployable = "DEPLOYABLE"
        case deprecated = "DEPRECATED"
        case failed = "FAILED"
        case initiated = "INITIATED"
        case requested = "REQUESTED"
        public var description: String { return self.rawValue }
    }

    public enum ComponentDependencyType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case hard = "HARD"
        case soft = "SOFT"
        public var description: String { return self.rawValue }
    }

    public enum ComponentVisibilityScope: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case `private` = "PRIVATE"
        case `public` = "PUBLIC"
        public var description: String { return self.rawValue }
    }

    public enum CoreDeviceStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case healthy = "HEALTHY"
        case unhealthy = "UNHEALTHY"
        public var description: String { return self.rawValue }
    }

    public enum DeploymentComponentUpdatePolicyAction: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case notifyComponents = "NOTIFY_COMPONENTS"
        case skipNotifyComponents = "SKIP_NOTIFY_COMPONENTS"
        public var description: String { return self.rawValue }
    }

    public enum DeploymentFailureHandlingPolicy: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case doNothing = "DO_NOTHING"
        case rollback = "ROLLBACK"
        public var description: String { return self.rawValue }
    }

    public enum DeploymentHistoryFilter: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case all = "ALL"
        case latestOnly = "LATEST_ONLY"
        public var description: String { return self.rawValue }
    }

    public enum DeploymentStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case active = "ACTIVE"
        case canceled = "CANCELED"
        case completed = "COMPLETED"
        case failed = "FAILED"
        case inactive = "INACTIVE"
        public var description: String { return self.rawValue }
    }

    public enum EffectiveDeploymentExecutionStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case canceled = "CANCELED"
        case completed = "COMPLETED"
        case failed = "FAILED"
        case inProgress = "IN_PROGRESS"
        case queued = "QUEUED"
        case rejected = "REJECTED"
        case succeeded = "SUCCEEDED"
        case timedOut = "TIMED_OUT"
        public var description: String { return self.rawValue }
    }

    public enum InstalledComponentLifecycleState: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case broken = "BROKEN"
        case errored = "ERRORED"
        case finished = "FINISHED"
        case installed = "INSTALLED"
        case new = "NEW"
        case running = "RUNNING"
        case starting = "STARTING"
        case stopping = "STOPPING"
        public var description: String { return self.rawValue }
    }

    public enum InstalledComponentTopologyFilter: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case all = "ALL"
        case root = "ROOT"
        public var description: String { return self.rawValue }
    }

    public enum IoTJobAbortAction: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case cancel = "CANCEL"
        public var description: String { return self.rawValue }
    }

    public enum IoTJobExecutionFailureType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case all = "ALL"
        case failed = "FAILED"
        case rejected = "REJECTED"
        case timedOut = "TIMED_OUT"
        public var description: String { return self.rawValue }
    }

    public enum IotEndpointType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case fips = "fips"
        case standard = "standard"
        public var description: String { return self.rawValue }
    }

    public enum LambdaEventSourceType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case iotCore = "IOT_CORE"
        case pubSub = "PUB_SUB"
        public var description: String { return self.rawValue }
    }

    public enum LambdaFilesystemPermission: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case ro = "ro"
        case rw = "rw"
        public var description: String { return self.rawValue }
    }

    public enum LambdaInputPayloadEncodingType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case binary = "binary"
        case json = "json"
        public var description: String { return self.rawValue }
    }

    public enum LambdaIsolationMode: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case greengrassContainer = "GreengrassContainer"
        case noContainer = "NoContainer"
        public var description: String { return self.rawValue }
    }

    public enum RecipeOutputFormat: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case json = "JSON"
        case yaml = "YAML"
        public var description: String { return self.rawValue }
    }

    public enum S3EndpointType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case global = "GLOBAL"
        case regional = "REGIONAL"
        public var description: String { return self.rawValue }
    }

    public enum ValidationExceptionReason: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case cannotParse = "CANNOT_PARSE"
        case fieldValidationFailed = "FIELD_VALIDATION_FAILED"
        case other = "OTHER"
        case unknownOperation = "UNKNOWN_OPERATION"
        public var description: String { return self.rawValue }
    }

    public enum VendorGuidance: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case active = "ACTIVE"
        case deleted = "DELETED"
        case discontinued = "DISCONTINUED"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct AssociateClientDeviceWithCoreDeviceEntry: AWSEncodableShape {
        /// The name of the IoT thing that represents the client device to associate.
        public let thingName: String

        @inlinable
        public init(thingName: String) {
            self.thingName = thingName
        }

        public func validate(name: String) throws {
            try self.validate(self.thingName, name: "thingName", parent: name, max: 128)
            try self.validate(self.thingName, name: "thingName", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case thingName = "thingName"
        }
    }

    public struct AssociateClientDeviceWithCoreDeviceErrorEntry: AWSDecodableShape {
        /// The error code for the request.
        public let code: String?
        /// A message that provides additional information about the error.
        public let message: String?
        /// The name of the IoT thing whose associate request failed.
        public let thingName: String?

        @inlinable
        public init(code: String? = nil, message: String? = nil, thingName: String? = nil) {
            self.code = code
            self.message = message
            self.thingName = thingName
        }

        private enum CodingKeys: String, CodingKey {
            case code = "code"
            case message = "message"
            case thingName = "thingName"
        }
    }

    public struct AssociateServiceRoleToAccountRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the service role to associate with IoT Greengrass for your Amazon Web Services account in this Amazon Web Services Region.
        public let roleArn: String

        @inlinable
        public init(roleArn: String) {
            self.roleArn = roleArn
        }

        private enum CodingKeys: String, CodingKey {
            case roleArn = "RoleArn"
        }
    }

    public struct AssociateServiceRoleToAccountResponse: AWSDecodableShape {
        /// The time when the service role was associated with IoT Greengrass for your Amazon Web Services account in this Amazon Web Services Region.
        public let associatedAt: String?

        @inlinable
        public init(associatedAt: String? = nil) {
            self.associatedAt = associatedAt
        }

        private enum CodingKeys: String, CodingKey {
            case associatedAt = "AssociatedAt"
        }
    }

    public struct AssociatedClientDevice: AWSDecodableShape {
        /// The time that the client device was associated, expressed in ISO 8601 format.
        public let associationTimestamp: Date?
        /// The name of the IoT thing that represents the associated client device.
        public let thingName: String?

        @inlinable
        public init(associationTimestamp: Date? = nil, thingName: String? = nil) {
            self.associationTimestamp = associationTimestamp
            self.thingName = thingName
        }

        private enum CodingKeys: String, CodingKey {
            case associationTimestamp = "associationTimestamp"
            case thingName = "thingName"
        }
    }

    public struct BatchAssociateClientDeviceWithCoreDeviceRequest: AWSEncodableShape {
        /// The name of the core device. This is also the name of the IoT thing.
        public let coreDeviceThingName: String
        /// The list of client devices to associate.
        public let entries: [AssociateClientDeviceWithCoreDeviceEntry]?

        @inlinable
        public init(coreDeviceThingName: String, entries: [AssociateClientDeviceWithCoreDeviceEntry]? = nil) {
            self.coreDeviceThingName = coreDeviceThingName
            self.entries = entries
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.coreDeviceThingName, key: "coreDeviceThingName")
            try container.encodeIfPresent(self.entries, forKey: .entries)
        }

        public func validate(name: String) throws {
            try self.validate(self.coreDeviceThingName, name: "coreDeviceThingName", parent: name, max: 128)
            try self.validate(self.coreDeviceThingName, name: "coreDeviceThingName", parent: name, min: 1)
            try self.entries?.forEach {
                try $0.validate(name: "\(name).entries[]")
            }
            try self.validate(self.entries, name: "entries", parent: name, max: 100)
            try self.validate(self.entries, name: "entries", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case entries = "entries"
        }
    }

    public struct BatchAssociateClientDeviceWithCoreDeviceResponse: AWSDecodableShape {
        /// The list of any errors for the entries in the request. Each error entry contains the name of the IoT thing that failed to associate.
        public let errorEntries: [AssociateClientDeviceWithCoreDeviceErrorEntry]?

        @inlinable
        public init(errorEntries: [AssociateClientDeviceWithCoreDeviceErrorEntry]? = nil) {
            self.errorEntries = errorEntries
        }

        private enum CodingKeys: String, CodingKey {
            case errorEntries = "errorEntries"
        }
    }

    public struct BatchDisassociateClientDeviceFromCoreDeviceRequest: AWSEncodableShape {
        /// The name of the core device. This is also the name of the IoT thing.
        public let coreDeviceThingName: String
        /// The list of client devices to disassociate.
        public let entries: [DisassociateClientDeviceFromCoreDeviceEntry]?

        @inlinable
        public init(coreDeviceThingName: String, entries: [DisassociateClientDeviceFromCoreDeviceEntry]? = nil) {
            self.coreDeviceThingName = coreDeviceThingName
            self.entries = entries
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.coreDeviceThingName, key: "coreDeviceThingName")
            try container.encodeIfPresent(self.entries, forKey: .entries)
        }

        public func validate(name: String) throws {
            try self.validate(self.coreDeviceThingName, name: "coreDeviceThingName", parent: name, max: 128)
            try self.validate(self.coreDeviceThingName, name: "coreDeviceThingName", parent: name, min: 1)
            try self.entries?.forEach {
                try $0.validate(name: "\(name).entries[]")
            }
            try self.validate(self.entries, name: "entries", parent: name, max: 100)
            try self.validate(self.entries, name: "entries", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case entries = "entries"
        }
    }

    public struct BatchDisassociateClientDeviceFromCoreDeviceResponse: AWSDecodableShape {
        /// The list of any errors for the entries in the request. Each error entry contains the name of the IoT thing that failed to disassociate.
        public let errorEntries: [DisassociateClientDeviceFromCoreDeviceErrorEntry]?

        @inlinable
        public init(errorEntries: [DisassociateClientDeviceFromCoreDeviceErrorEntry]? = nil) {
            self.errorEntries = errorEntries
        }

        private enum CodingKeys: String, CodingKey {
            case errorEntries = "errorEntries"
        }
    }

    public struct CancelDeploymentRequest: AWSEncodableShape {
        /// The ID of the deployment.
        public let deploymentId: String

        @inlinable
        public init(deploymentId: String) {
            self.deploymentId = deploymentId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.deploymentId, key: "deploymentId")
        }

        public func validate(name: String) throws {
            try self.validate(self.deploymentId, name: "deploymentId", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct CancelDeploymentResponse: AWSDecodableShape {
        /// A message that communicates if the cancel was successful.
        public let message: String?

        @inlinable
        public init(message: String? = nil) {
            self.message = message
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
        }
    }

    public struct CloudComponentStatus: AWSDecodableShape {
        /// The state of the component version.
        public let componentState: CloudComponentState?
        /// A dictionary of errors that communicate why the component version is in an error state. For example, if IoT Greengrass can't access an artifact for the component version, then errors contains the artifact's URI as a key, and the error message as the value for that key.
        public let errors: [String: String]?
        /// A message that communicates details, such as errors, about the status of the component version.
        public let message: String?
        /// The vendor guidance state for the component version. This state indicates whether the component version has any issues that you should consider before you deploy it. The vendor guidance state can be:    ACTIVE – This component version is available and recommended for use.    DISCONTINUED – This component version has been discontinued by its publisher. You can deploy this component version, but we recommend that you use a different version of this component.    DELETED – This component version has been deleted by its publisher, so you can't deploy it. If you have any existing deployments that specify this component version, those deployments will fail.
        public let vendorGuidance: VendorGuidance?
        /// A message that communicates details about the vendor guidance state of the component version. This message communicates why a component version is discontinued or deleted.
        public let vendorGuidanceMessage: String?

        @inlinable
        public init(componentState: CloudComponentState? = nil, errors: [String: String]? = nil, message: String? = nil, vendorGuidance: VendorGuidance? = nil, vendorGuidanceMessage: String? = nil) {
            self.componentState = componentState
            self.errors = errors
            self.message = message
            self.vendorGuidance = vendorGuidance
            self.vendorGuidanceMessage = vendorGuidanceMessage
        }

        private enum CodingKeys: String, CodingKey {
            case componentState = "componentState"
            case errors = "errors"
            case message = "message"
            case vendorGuidance = "vendorGuidance"
            case vendorGuidanceMessage = "vendorGuidanceMessage"
        }
    }

    public struct Component: AWSDecodableShape {
        /// The ARN of the component version.
        public let arn: String?
        /// The name of the component.
        public let componentName: String?
        /// The latest version of the component and its details.
        public let latestVersion: ComponentLatestVersion?

        @inlinable
        public init(arn: String? = nil, componentName: String? = nil, latestVersion: ComponentLatestVersion? = nil) {
            self.arn = arn
            self.componentName = componentName
            self.latestVersion = latestVersion
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case componentName = "componentName"
            case latestVersion = "latestVersion"
        }
    }

    public struct ComponentCandidate: AWSEncodableShape {
        /// The name of the component.
        public let componentName: String?
        /// The version of the component.
        public let componentVersion: String?
        /// The version requirements for the component's dependencies. Greengrass core devices get the version requirements from component recipes. IoT Greengrass V2 uses semantic version constraints. For more information, see Semantic Versioning.
        public let versionRequirements: [String: String]?

        @inlinable
        public init(componentName: String? = nil, componentVersion: String? = nil, versionRequirements: [String: String]? = nil) {
            self.componentName = componentName
            self.componentVersion = componentVersion
            self.versionRequirements = versionRequirements
        }

        public func validate(name: String) throws {
            try self.validate(self.componentName, name: "componentName", parent: name, max: 128)
            try self.validate(self.componentName, name: "componentName", parent: name, min: 1)
            try self.validate(self.componentVersion, name: "componentVersion", parent: name, max: 64)
            try self.validate(self.componentVersion, name: "componentVersion", parent: name, min: 1)
            try self.versionRequirements?.forEach {
                try validate($0.key, name: "versionRequirements.key", parent: name, min: 1)
                try validate($0.value, name: "versionRequirements[\"\($0.key)\"]", parent: name, min: 1)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case componentName = "componentName"
            case componentVersion = "componentVersion"
            case versionRequirements = "versionRequirements"
        }
    }

    public struct ComponentConfigurationUpdate: AWSEncodableShape & AWSDecodableShape {
        /// A serialized JSON string that contains the configuration object to merge to target devices. The core device merges this configuration with the component's existing configuration. If this is the first time a component deploys on a device, the core device merges this configuration with the component's default configuration. This means that the core device keeps it's existing configuration for keys and values that you don't specify in this object. For more information, see Merge configuration updates in the IoT Greengrass V2 Developer Guide.
        public let merge: String?
        /// The list of configuration nodes to reset to default values on target devices. Use JSON pointers to specify each node to reset. JSON pointers start with a forward slash (/) and use forward slashes to separate the key for each level in the object. For more information, see the JSON pointer specification and Reset configuration updates in the IoT Greengrass V2 Developer Guide.
        public let reset: [String]?

        @inlinable
        public init(merge: String? = nil, reset: [String]? = nil) {
            self.merge = merge
            self.reset = reset
        }

        public func validate(name: String) throws {
            try self.validate(self.merge, name: "merge", parent: name, max: 10485760)
            try self.validate(self.merge, name: "merge", parent: name, min: 1)
            try self.reset?.forEach {
                try validate($0, name: "reset[]", parent: name, max: 256)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case merge = "merge"
            case reset = "reset"
        }
    }

    public struct ComponentDependencyRequirement: AWSEncodableShape {
        /// The type of this dependency. Choose from the following options:    SOFT – The component doesn't restart if the dependency changes state.    HARD – The component restarts if the dependency changes state.   Default: HARD
        public let dependencyType: ComponentDependencyType?
        /// The component version requirement for the component dependency. IoT Greengrass V2 uses semantic version constraints. For more information, see Semantic Versioning.
        public let versionRequirement: String?

        @inlinable
        public init(dependencyType: ComponentDependencyType? = nil, versionRequirement: String? = nil) {
            self.dependencyType = dependencyType
            self.versionRequirement = versionRequirement
        }

        public func validate(name: String) throws {
            try self.validate(self.versionRequirement, name: "versionRequirement", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case dependencyType = "dependencyType"
            case versionRequirement = "versionRequirement"
        }
    }

    public struct ComponentDeploymentSpecification: AWSEncodableShape & AWSDecodableShape {
        /// The version of the component.
        public let componentVersion: String
        /// The configuration updates to deploy for the component. You can define reset updates and merge updates. A reset updates the keys that you specify to the default configuration for the component. A merge updates the core device's component configuration with the keys and values that you specify. The IoT Greengrass Core software applies reset updates before it applies merge updates. For more information, see Update component configurations in the IoT Greengrass V2 Developer Guide.
        public let configurationUpdate: ComponentConfigurationUpdate?
        /// The system user and group that the IoT Greengrass Core software uses to run component processes on the core device. If you omit this parameter, the IoT Greengrass Core software uses the system user and group that you configure for the core device. For more information, see Configure the user and group that run components in the IoT Greengrass V2 Developer Guide.
        public let runWith: ComponentRunWith?

        @inlinable
        public init(componentVersion: String, configurationUpdate: ComponentConfigurationUpdate? = nil, runWith: ComponentRunWith? = nil) {
            self.componentVersion = componentVersion
            self.configurationUpdate = configurationUpdate
            self.runWith = runWith
        }

        public func validate(name: String) throws {
            try self.validate(self.componentVersion, name: "componentVersion", parent: name, max: 64)
            try self.validate(self.componentVersion, name: "componentVersion", parent: name, min: 1)
            try self.configurationUpdate?.validate(name: "\(name).configurationUpdate")
            try self.runWith?.validate(name: "\(name).runWith")
        }

        private enum CodingKeys: String, CodingKey {
            case componentVersion = "componentVersion"
            case configurationUpdate = "configurationUpdate"
            case runWith = "runWith"
        }
    }

    public struct ComponentLatestVersion: AWSDecodableShape {
        /// The ARN of the component version.
        public let arn: String?
        /// The version of the component.
        public let componentVersion: String?
        /// The time at which the component was created, expressed in ISO 8601 format.
        public let creationTimestamp: Date?
        /// The description of the component version.
        public let description: String?
        /// The platforms that the component version supports.
        public let platforms: [ComponentPlatform]?
        /// The publisher of the component version.
        public let publisher: String?

        @inlinable
        public init(arn: String? = nil, componentVersion: String? = nil, creationTimestamp: Date? = nil, description: String? = nil, platforms: [ComponentPlatform]? = nil, publisher: String? = nil) {
            self.arn = arn
            self.componentVersion = componentVersion
            self.creationTimestamp = creationTimestamp
            self.description = description
            self.platforms = platforms
            self.publisher = publisher
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case componentVersion = "componentVersion"
            case creationTimestamp = "creationTimestamp"
            case description = "description"
            case platforms = "platforms"
            case publisher = "publisher"
        }
    }

    public struct ComponentPlatform: AWSEncodableShape & AWSDecodableShape {
        /// A dictionary of attributes for the platform. The IoT Greengrass Core software defines the os and architecture by default. You can specify additional platform attributes for a core device when you deploy the Greengrass nucleus component. For more information, see the Greengrass nucleus component in the IoT Greengrass V2 Developer Guide.
        public let attributes: [String: String]?
        /// The friendly name of the platform. This name helps you identify the platform. If you omit this parameter, IoT Greengrass creates a friendly name from the os and architecture of the platform.
        public let name: String?

        @inlinable
        public init(attributes: [String: String]? = nil, name: String? = nil) {
            self.attributes = attributes
            self.name = name
        }

        public func validate(name: String) throws {
            try self.attributes?.forEach {
                try validate($0.key, name: "attributes.key", parent: name, min: 1)
                try validate($0.value, name: "attributes[\"\($0.key)\"]", parent: name, min: 1)
            }
            try self.validate(self.name, name: "name", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case attributes = "attributes"
            case name = "name"
        }
    }

    public struct ComponentRunWith: AWSEncodableShape & AWSDecodableShape {
        /// The POSIX system user and, optionally, group to use to run this component on Linux core devices. The user, and group if specified, must exist on each Linux core device. Specify the user and group separated by a colon (:) in the following format: user:group. The group is optional. If you don't specify a group, the IoT Greengrass Core software uses the primary user for the group. If you omit this parameter, the IoT Greengrass Core software uses the default system user and group that you configure on the Greengrass nucleus component. For more information, see Configure the user and group that run components.
        public let posixUser: String?
        /// The system resource limits to apply to this component's process on the core device. IoT Greengrass currently supports this feature on only Linux core devices. If you omit this parameter, the IoT Greengrass Core software uses the default system resource limits that you configure on the Greengrass nucleus component. For more information, see Configure system resource limits for components.
        public let systemResourceLimits: SystemResourceLimits?
        /// The Windows user to use to run this component on Windows core devices. The user must exist on each Windows core device, and its name and password must be in the LocalSystem account's Credentials Manager instance. If you omit this parameter, the IoT Greengrass Core software uses the default Windows user that you configure on the Greengrass nucleus component. For more information, see Configure the user and group that run components.
        public let windowsUser: String?

        @inlinable
        public init(posixUser: String? = nil, systemResourceLimits: SystemResourceLimits? = nil, windowsUser: String? = nil) {
            self.posixUser = posixUser
            self.systemResourceLimits = systemResourceLimits
            self.windowsUser = windowsUser
        }

        public func validate(name: String) throws {
            try self.validate(self.posixUser, name: "posixUser", parent: name, min: 1)
            try self.systemResourceLimits?.validate(name: "\(name).systemResourceLimits")
            try self.validate(self.windowsUser, name: "windowsUser", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case posixUser = "posixUser"
            case systemResourceLimits = "systemResourceLimits"
            case windowsUser = "windowsUser"
        }
    }

    public struct ComponentVersionListItem: AWSDecodableShape {
        /// The ARN of the component version.
        public let arn: String?
        /// The name of the component.
        public let componentName: String?
        /// The version of the component.
        public let componentVersion: String?

        @inlinable
        public init(arn: String? = nil, componentName: String? = nil, componentVersion: String? = nil) {
            self.arn = arn
            self.componentName = componentName
            self.componentVersion = componentVersion
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case componentName = "componentName"
            case componentVersion = "componentVersion"
        }
    }

    public struct ConflictException: AWSErrorShape {
        public let message: String
        /// The ID of the resource that conflicts with the request.
        public let resourceId: String
        /// The type of the resource that conflicts with the request.
        public let resourceType: String

        @inlinable
        public init(message: String, resourceId: String, resourceType: String) {
            self.message = message
            self.resourceId = resourceId
            self.resourceType = resourceType
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case resourceId = "resourceId"
            case resourceType = "resourceType"
        }
    }

    public struct ConnectivityInfo: AWSEncodableShape & AWSDecodableShape {
        /// The IP address or DNS address where client devices can connect to an MQTT broker on the Greengrass core device.
        public let hostAddress: String?
        /// An ID for the connectivity information.
        public let id: String?
        /// Additional metadata to provide to client devices that connect to this core device.
        public let metadata: String?
        /// The port where the MQTT broker operates on the core device. This port is typically 8883, which is the default port for the MQTT broker component that runs on core devices.
        public let portNumber: Int?

        @inlinable
        public init(hostAddress: String? = nil, id: String? = nil, metadata: String? = nil, portNumber: Int? = nil) {
            self.hostAddress = hostAddress
            self.id = id
            self.metadata = metadata
            self.portNumber = portNumber
        }

        public func validate(name: String) throws {
            try self.validate(self.portNumber, name: "portNumber", parent: name, max: 65535)
            try self.validate(self.portNumber, name: "portNumber", parent: name, min: 0)
        }

        private enum CodingKeys: String, CodingKey {
            case hostAddress = "HostAddress"
            case id = "Id"
            case metadata = "Metadata"
            case portNumber = "PortNumber"
        }
    }

    public struct CoreDevice: AWSDecodableShape {
        /// The computer architecture of the core device.
        public let architecture: String?
        /// The name of the core device. This is also the name of the IoT thing.
        public let coreDeviceThingName: String?
        /// The time at which the core device's status last updated, expressed in ISO 8601 format.
        public let lastStatusUpdateTimestamp: Date?
        /// The operating system platform that the core device runs.
        public let platform: String?
        /// The runtime for the core device. The runtime can be:    aws_nucleus_classic     aws_nucleus_lite
        public let runtime: String?
        /// The status of the core device. Core devices can have the following statuses:    HEALTHY – The IoT Greengrass Core software and all components run on the core device without issue.    UNHEALTHY – The IoT Greengrass Core software or a component is in a failed state on the core device.
        public let status: CoreDeviceStatus?

        @inlinable
        public init(architecture: String? = nil, coreDeviceThingName: String? = nil, lastStatusUpdateTimestamp: Date? = nil, platform: String? = nil, runtime: String? = nil, status: CoreDeviceStatus? = nil) {
            self.architecture = architecture
            self.coreDeviceThingName = coreDeviceThingName
            self.lastStatusUpdateTimestamp = lastStatusUpdateTimestamp
            self.platform = platform
            self.runtime = runtime
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case architecture = "architecture"
            case coreDeviceThingName = "coreDeviceThingName"
            case lastStatusUpdateTimestamp = "lastStatusUpdateTimestamp"
            case platform = "platform"
            case runtime = "runtime"
            case status = "status"
        }
    }

    public struct CreateComponentVersionRequest: AWSEncodableShape {
        /// A unique, case-sensitive identifier that you can provide to ensure that the request is idempotent.  Idempotency means that the request is successfully processed only once, even if you send the request multiple times.  When a request succeeds, and you specify the same client token for subsequent successful requests, the IoT Greengrass V2 service  returns the successful response that it caches from the previous request. IoT Greengrass V2 caches successful responses for  idempotent requests for up to 8 hours.
        public let clientToken: String?
        /// The recipe to use to create the component. The recipe defines the component's metadata, parameters, dependencies, lifecycle, artifacts, and platform compatibility. You must specify either inlineRecipe or lambdaFunction.
        public let inlineRecipe: AWSBase64Data?
        /// The parameters to create a component from a Lambda function. You must specify either inlineRecipe or lambdaFunction.
        public let lambdaFunction: LambdaFunctionRecipeSource?
        /// A list of key-value pairs that contain metadata for the resource. For more information, see Tag your resources in the IoT Greengrass V2 Developer Guide.
        public let tags: [String: String]?

        @inlinable
        public init(clientToken: String? = CreateComponentVersionRequest.idempotencyToken(), inlineRecipe: AWSBase64Data? = nil, lambdaFunction: LambdaFunctionRecipeSource? = nil, tags: [String: String]? = nil) {
            self.clientToken = clientToken
            self.inlineRecipe = inlineRecipe
            self.lambdaFunction = lambdaFunction
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 64)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.lambdaFunction?.validate(name: "\(name).lambdaFunction")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "clientToken"
            case inlineRecipe = "inlineRecipe"
            case lambdaFunction = "lambdaFunction"
            case tags = "tags"
        }
    }

    public struct CreateComponentVersionResponse: AWSDecodableShape {
        /// The ARN of the component version.
        public let arn: String?
        /// The name of the component.
        public let componentName: String
        /// The version of the component.
        public let componentVersion: String
        /// The time at which the component was created, expressed in ISO 8601 format.
        public let creationTimestamp: Date
        /// The status of the component version in IoT Greengrass V2. This status is different from the status of the component on a core device.
        public let status: CloudComponentStatus

        @inlinable
        public init(arn: String? = nil, componentName: String, componentVersion: String, creationTimestamp: Date, status: CloudComponentStatus) {
            self.arn = arn
            self.componentName = componentName
            self.componentVersion = componentVersion
            self.creationTimestamp = creationTimestamp
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case componentName = "componentName"
            case componentVersion = "componentVersion"
            case creationTimestamp = "creationTimestamp"
            case status = "status"
        }
    }

    public struct CreateDeploymentRequest: AWSEncodableShape {
        /// A unique, case-sensitive identifier that you can provide to ensure that the request is idempotent.  Idempotency means that the request is successfully processed only once, even if you send the request multiple times.  When a request succeeds, and you specify the same client token for subsequent successful requests, the IoT Greengrass V2 service  returns the successful response that it caches from the previous request. IoT Greengrass V2 caches successful responses for  idempotent requests for up to 8 hours.
        public let clientToken: String?
        /// The components to deploy. This is a dictionary, where each key is the name of a component, and each key's value is the version and configuration to deploy for that component.
        public let components: [String: ComponentDeploymentSpecification]?
        /// The name of the deployment.
        public let deploymentName: String?
        /// The deployment policies for the deployment. These policies define how the deployment updates components and handles failure.
        public let deploymentPolicies: DeploymentPolicies?
        /// The job configuration for the deployment configuration. The job configuration specifies the rollout, timeout, and stop configurations for the deployment configuration.
        public let iotJobConfiguration: DeploymentIoTJobConfiguration?
        /// The parent deployment's target ARN within a subdeployment.
        public let parentTargetArn: String?
        /// A list of key-value pairs that contain metadata for the resource. For more information, see Tag your resources in the IoT Greengrass V2 Developer Guide.
        public let tags: [String: String]?
        /// The ARN of the target IoT thing or thing group. When creating a subdeployment, the targetARN can only be a thing group.
        public let targetArn: String

        @inlinable
        public init(clientToken: String? = CreateDeploymentRequest.idempotencyToken(), components: [String: ComponentDeploymentSpecification]? = nil, deploymentName: String? = nil, deploymentPolicies: DeploymentPolicies? = nil, iotJobConfiguration: DeploymentIoTJobConfiguration? = nil, parentTargetArn: String? = nil, tags: [String: String]? = nil, targetArn: String) {
            self.clientToken = clientToken
            self.components = components
            self.deploymentName = deploymentName
            self.deploymentPolicies = deploymentPolicies
            self.iotJobConfiguration = iotJobConfiguration
            self.parentTargetArn = parentTargetArn
            self.tags = tags
            self.targetArn = targetArn
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 64)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.components?.forEach {
                try validate($0.key, name: "components.key", parent: name, min: 1)
                try $0.value.validate(name: "\(name).components[\"\($0.key)\"]")
            }
            try self.validate(self.deploymentName, name: "deploymentName", parent: name, max: 256)
            try self.validate(self.deploymentName, name: "deploymentName", parent: name, min: 1)
            try self.iotJobConfiguration?.validate(name: "\(name).iotJobConfiguration")
            try self.validate(self.parentTargetArn, name: "parentTargetArn", parent: name, pattern: "^arn:[^:]*:iot:[^:]*:[0-9]+:thinggroup/.+$")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
            try self.validate(self.targetArn, name: "targetArn", parent: name, pattern: "^arn:[^:]*:iot:[^:]*:[0-9]+:(thing|thinggroup)/.+$")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "clientToken"
            case components = "components"
            case deploymentName = "deploymentName"
            case deploymentPolicies = "deploymentPolicies"
            case iotJobConfiguration = "iotJobConfiguration"
            case parentTargetArn = "parentTargetArn"
            case tags = "tags"
            case targetArn = "targetArn"
        }
    }

    public struct CreateDeploymentResponse: AWSDecodableShape {
        /// The ID of the deployment.
        public let deploymentId: String?
        /// The ARN of the IoT job that applies the deployment to target devices.
        public let iotJobArn: String?
        /// The ID of the IoT job that applies the deployment to target devices.
        public let iotJobId: String?

        @inlinable
        public init(deploymentId: String? = nil, iotJobArn: String? = nil, iotJobId: String? = nil) {
            self.deploymentId = deploymentId
            self.iotJobArn = iotJobArn
            self.iotJobId = iotJobId
        }

        private enum CodingKeys: String, CodingKey {
            case deploymentId = "deploymentId"
            case iotJobArn = "iotJobArn"
            case iotJobId = "iotJobId"
        }
    }

    public struct DeleteComponentRequest: AWSEncodableShape {
        /// The ARN of the component version.
        public let arn: String

        @inlinable
        public init(arn: String) {
            self.arn = arn
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.arn, key: "arn")
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:[^:]*:greengrass:[^:]*:(aws|[0-9]+):components:[^:]+:versions:[^:]+$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteCoreDeviceRequest: AWSEncodableShape {
        /// The name of the core device. This is also the name of the IoT thing.
        public let coreDeviceThingName: String

        @inlinable
        public init(coreDeviceThingName: String) {
            self.coreDeviceThingName = coreDeviceThingName
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.coreDeviceThingName, key: "coreDeviceThingName")
        }

        public func validate(name: String) throws {
            try self.validate(self.coreDeviceThingName, name: "coreDeviceThingName", parent: name, max: 128)
            try self.validate(self.coreDeviceThingName, name: "coreDeviceThingName", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteDeploymentRequest: AWSEncodableShape {
        /// The ID of the deployment.
        public let deploymentId: String

        @inlinable
        public init(deploymentId: String) {
            self.deploymentId = deploymentId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.deploymentId, key: "deploymentId")
        }

        public func validate(name: String) throws {
            try self.validate(self.deploymentId, name: "deploymentId", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct Deployment: AWSDecodableShape {
        /// The time at which the deployment was created, expressed in ISO 8601 format.
        public let creationTimestamp: Date?
        /// The ID of the deployment.
        public let deploymentId: String?
        /// The name of the deployment.
        public let deploymentName: String?
        /// The status of the deployment.
        public let deploymentStatus: DeploymentStatus?
        /// Whether or not the deployment is the latest revision for its target.
        public let isLatestForTarget: Bool?
        /// The parent deployment's target ARN within a subdeployment.
        public let parentTargetArn: String?
        /// The revision number of the deployment.
        public let revisionId: String?
        /// The ARN of the target IoT thing or thing group. When creating a subdeployment, the targetARN can only be a thing group.
        public let targetArn: String?

        @inlinable
        public init(creationTimestamp: Date? = nil, deploymentId: String? = nil, deploymentName: String? = nil, deploymentStatus: DeploymentStatus? = nil, isLatestForTarget: Bool? = nil, parentTargetArn: String? = nil, revisionId: String? = nil, targetArn: String? = nil) {
            self.creationTimestamp = creationTimestamp
            self.deploymentId = deploymentId
            self.deploymentName = deploymentName
            self.deploymentStatus = deploymentStatus
            self.isLatestForTarget = isLatestForTarget
            self.parentTargetArn = parentTargetArn
            self.revisionId = revisionId
            self.targetArn = targetArn
        }

        private enum CodingKeys: String, CodingKey {
            case creationTimestamp = "creationTimestamp"
            case deploymentId = "deploymentId"
            case deploymentName = "deploymentName"
            case deploymentStatus = "deploymentStatus"
            case isLatestForTarget = "isLatestForTarget"
            case parentTargetArn = "parentTargetArn"
            case revisionId = "revisionId"
            case targetArn = "targetArn"
        }
    }

    public struct DeploymentComponentUpdatePolicy: AWSEncodableShape & AWSDecodableShape {
        /// Whether or not to notify components and wait for components to become safe to update. Choose from the following options:    NOTIFY_COMPONENTS – The deployment notifies each component before it stops and updates that component. Components can use the SubscribeToComponentUpdates IPC operation to receive these notifications. Then, components can respond with the DeferComponentUpdate IPC operation. For more information, see Create deployments in the IoT Greengrass V2 Developer Guide.    SKIP_NOTIFY_COMPONENTS – The deployment doesn't notify components or wait for them to be safe to update.   Default: NOTIFY_COMPONENTS
        public let action: DeploymentComponentUpdatePolicyAction?
        /// The amount of time in seconds that each component on a device has to report that it's safe to update. If the component waits for longer than this timeout, then the deployment proceeds on the device. Default: 60
        public let timeoutInSeconds: Int?

        @inlinable
        public init(action: DeploymentComponentUpdatePolicyAction? = nil, timeoutInSeconds: Int? = nil) {
            self.action = action
            self.timeoutInSeconds = timeoutInSeconds
        }

        private enum CodingKeys: String, CodingKey {
            case action = "action"
            case timeoutInSeconds = "timeoutInSeconds"
        }
    }

    public struct DeploymentConfigurationValidationPolicy: AWSEncodableShape & AWSDecodableShape {
        /// The amount of time in seconds that a component can validate its configuration updates. If the validation time exceeds this timeout, then the deployment proceeds for the device. Default: 30
        public let timeoutInSeconds: Int?

        @inlinable
        public init(timeoutInSeconds: Int? = nil) {
            self.timeoutInSeconds = timeoutInSeconds
        }

        private enum CodingKeys: String, CodingKey {
            case timeoutInSeconds = "timeoutInSeconds"
        }
    }

    public struct DeploymentIoTJobConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// The stop configuration for the job. This configuration defines when and how to stop a job rollout.
        public let abortConfig: IoTJobAbortConfig?
        /// The rollout configuration for the job. This configuration defines the rate at which the job rolls out to the fleet of target devices.
        public let jobExecutionsRolloutConfig: IoTJobExecutionsRolloutConfig?
        /// The timeout configuration for the job. This configuration defines the amount of time each device has to complete the job.
        public let timeoutConfig: IoTJobTimeoutConfig?

        @inlinable
        public init(abortConfig: IoTJobAbortConfig? = nil, jobExecutionsRolloutConfig: IoTJobExecutionsRolloutConfig? = nil, timeoutConfig: IoTJobTimeoutConfig? = nil) {
            self.abortConfig = abortConfig
            self.jobExecutionsRolloutConfig = jobExecutionsRolloutConfig
            self.timeoutConfig = timeoutConfig
        }

        public func validate(name: String) throws {
            try self.abortConfig?.validate(name: "\(name).abortConfig")
            try self.jobExecutionsRolloutConfig?.validate(name: "\(name).jobExecutionsRolloutConfig")
        }

        private enum CodingKeys: String, CodingKey {
            case abortConfig = "abortConfig"
            case jobExecutionsRolloutConfig = "jobExecutionsRolloutConfig"
            case timeoutConfig = "timeoutConfig"
        }
    }

    public struct DeploymentPolicies: AWSEncodableShape & AWSDecodableShape {
        /// The component update policy for the configuration deployment. This policy defines when it's safe to deploy the configuration to devices.
        public let componentUpdatePolicy: DeploymentComponentUpdatePolicy?
        /// The configuration validation policy for the configuration deployment. This policy defines how long each component has to validate its configure updates.
        public let configurationValidationPolicy: DeploymentConfigurationValidationPolicy?
        /// The failure handling policy for the configuration deployment. This policy defines what to do if the deployment fails. Default: ROLLBACK
        public let failureHandlingPolicy: DeploymentFailureHandlingPolicy?

        @inlinable
        public init(componentUpdatePolicy: DeploymentComponentUpdatePolicy? = nil, configurationValidationPolicy: DeploymentConfigurationValidationPolicy? = nil, failureHandlingPolicy: DeploymentFailureHandlingPolicy? = nil) {
            self.componentUpdatePolicy = componentUpdatePolicy
            self.configurationValidationPolicy = configurationValidationPolicy
            self.failureHandlingPolicy = failureHandlingPolicy
        }

        private enum CodingKeys: String, CodingKey {
            case componentUpdatePolicy = "componentUpdatePolicy"
            case configurationValidationPolicy = "configurationValidationPolicy"
            case failureHandlingPolicy = "failureHandlingPolicy"
        }
    }

    public struct DescribeComponentRequest: AWSEncodableShape {
        /// The ARN of the component version.
        public let arn: String

        @inlinable
        public init(arn: String) {
            self.arn = arn
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.arn, key: "arn")
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:[^:]*:greengrass:[^:]*:(aws|[0-9]+):components:[^:]+:versions:[^:]+$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DescribeComponentResponse: AWSDecodableShape {
        /// The ARN of the component version.
        public let arn: String?
        /// The name of the component.
        public let componentName: String?
        /// The version of the component.
        public let componentVersion: String?
        /// The time at which the component was created, expressed in ISO 8601 format.
        public let creationTimestamp: Date?
        /// The description of the component version.
        public let description: String?
        /// The platforms that the component version supports.
        public let platforms: [ComponentPlatform]?
        /// The publisher of the component version.
        public let publisher: String?
        /// The status of the component version in IoT Greengrass V2. This status is different from the status of the component on a core device.
        public let status: CloudComponentStatus?
        /// A list of key-value pairs that contain metadata for the resource. For more information, see Tag your resources in the IoT Greengrass V2 Developer Guide.
        public let tags: [String: String]?

        @inlinable
        public init(arn: String? = nil, componentName: String? = nil, componentVersion: String? = nil, creationTimestamp: Date? = nil, description: String? = nil, platforms: [ComponentPlatform]? = nil, publisher: String? = nil, status: CloudComponentStatus? = nil, tags: [String: String]? = nil) {
            self.arn = arn
            self.componentName = componentName
            self.componentVersion = componentVersion
            self.creationTimestamp = creationTimestamp
            self.description = description
            self.platforms = platforms
            self.publisher = publisher
            self.status = status
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case componentName = "componentName"
            case componentVersion = "componentVersion"
            case creationTimestamp = "creationTimestamp"
            case description = "description"
            case platforms = "platforms"
            case publisher = "publisher"
            case status = "status"
            case tags = "tags"
        }
    }

    public struct DisassociateClientDeviceFromCoreDeviceEntry: AWSEncodableShape {
        /// The name of the IoT thing that represents the client device to disassociate.
        public let thingName: String

        @inlinable
        public init(thingName: String) {
            self.thingName = thingName
        }

        public func validate(name: String) throws {
            try self.validate(self.thingName, name: "thingName", parent: name, max: 128)
            try self.validate(self.thingName, name: "thingName", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case thingName = "thingName"
        }
    }

    public struct DisassociateClientDeviceFromCoreDeviceErrorEntry: AWSDecodableShape {
        /// The error code for the request.
        public let code: String?
        /// A message that provides additional information about the error.
        public let message: String?
        /// The name of the IoT thing whose disassociate request failed.
        public let thingName: String?

        @inlinable
        public init(code: String? = nil, message: String? = nil, thingName: String? = nil) {
            self.code = code
            self.message = message
            self.thingName = thingName
        }

        private enum CodingKeys: String, CodingKey {
            case code = "code"
            case message = "message"
            case thingName = "thingName"
        }
    }

    public struct DisassociateServiceRoleFromAccountRequest: AWSEncodableShape {
        public init() {}
    }

    public struct DisassociateServiceRoleFromAccountResponse: AWSDecodableShape {
        /// The time when the service role was disassociated from IoT Greengrass for your Amazon Web Services account in this Amazon Web Services Region.
        public let disassociatedAt: String?

        @inlinable
        public init(disassociatedAt: String? = nil) {
            self.disassociatedAt = disassociatedAt
        }

        private enum CodingKeys: String, CodingKey {
            case disassociatedAt = "DisassociatedAt"
        }
    }

    public struct EffectiveDeployment: AWSDecodableShape {
        /// The status of the deployment job on the Greengrass core device.    IN_PROGRESS – The deployment job is running.    QUEUED – The deployment job is in the job queue and waiting to run.    FAILED – The deployment failed. For more information, see the statusDetails field.    COMPLETED – The deployment to an IoT thing was completed successfully.    TIMED_OUT – The deployment didn't complete in the allotted time.     CANCELED – The deployment was canceled by the user.    REJECTED – The deployment was rejected. For more information, see the statusDetails field.    SUCCEEDED – The deployment to an IoT thing group was completed successfully.
        public let coreDeviceExecutionStatus: EffectiveDeploymentExecutionStatus
        /// The time at which the deployment was created, expressed in ISO 8601 format.
        public let creationTimestamp: Date
        /// The ID of the deployment.
        public let deploymentId: String
        /// The name of the deployment.
        public let deploymentName: String
        /// The description of the deployment job.
        public let description: String?
        /// The ARN of the IoT job that applies the deployment to target devices.
        public let iotJobArn: String?
        /// The ID of the IoT job that applies the deployment to target devices.
        public let iotJobId: String?
        /// The time at which the deployment job was last modified, expressed in ISO 8601 format.
        public let modifiedTimestamp: Date
        /// The reason code for the update, if the job was updated.
        public let reason: String?
        /// The status details that explain why a deployment has an error. This response will be null if the deployment is in a success state.
        public let statusDetails: EffectiveDeploymentStatusDetails?
        /// The ARN of the target IoT thing or thing group.
        public let targetArn: String

        @inlinable
        public init(coreDeviceExecutionStatus: EffectiveDeploymentExecutionStatus, creationTimestamp: Date, deploymentId: String, deploymentName: String, description: String? = nil, iotJobArn: String? = nil, iotJobId: String? = nil, modifiedTimestamp: Date, reason: String? = nil, statusDetails: EffectiveDeploymentStatusDetails? = nil, targetArn: String) {
            self.coreDeviceExecutionStatus = coreDeviceExecutionStatus
            self.creationTimestamp = creationTimestamp
            self.deploymentId = deploymentId
            self.deploymentName = deploymentName
            self.description = description
            self.iotJobArn = iotJobArn
            self.iotJobId = iotJobId
            self.modifiedTimestamp = modifiedTimestamp
            self.reason = reason
            self.statusDetails = statusDetails
            self.targetArn = targetArn
        }

        private enum CodingKeys: String, CodingKey {
            case coreDeviceExecutionStatus = "coreDeviceExecutionStatus"
            case creationTimestamp = "creationTimestamp"
            case deploymentId = "deploymentId"
            case deploymentName = "deploymentName"
            case description = "description"
            case iotJobArn = "iotJobArn"
            case iotJobId = "iotJobId"
            case modifiedTimestamp = "modifiedTimestamp"
            case reason = "reason"
            case statusDetails = "statusDetails"
            case targetArn = "targetArn"
        }
    }

    public struct EffectiveDeploymentStatusDetails: AWSDecodableShape {
        /// Contains an ordered list of short error codes that range from the most generic error to the most specific one. The error codes describe the reason for failure whenever the coreDeviceExecutionStatus is in a failed state. The response will be an empty list if there is no error.
        public let errorStack: [String]?
        /// Contains tags which describe the error. You can use the error types to classify errors to assist with remediating the failure. The response will be an empty list if there is no error.
        public let errorTypes: [String]?

        @inlinable
        public init(errorStack: [String]? = nil, errorTypes: [String]? = nil) {
            self.errorStack = errorStack
            self.errorTypes = errorTypes
        }

        private enum CodingKeys: String, CodingKey {
            case errorStack = "errorStack"
            case errorTypes = "errorTypes"
        }
    }

    public struct GetComponentRequest: AWSEncodableShape {
        /// The ARN of the component version.
        public let arn: String
        /// The format of the recipe.
        public let recipeOutputFormat: RecipeOutputFormat?

        @inlinable
        public init(arn: String, recipeOutputFormat: RecipeOutputFormat? = nil) {
            self.arn = arn
            self.recipeOutputFormat = recipeOutputFormat
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.arn, key: "arn")
            request.encodeQuery(self.recipeOutputFormat, key: "recipeOutputFormat")
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:[^:]*:greengrass:[^:]*:(aws|[0-9]+):components:[^:]+:versions:[^:]+$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetComponentResponse: AWSDecodableShape {
        /// The recipe of the component version.
        public let recipe: AWSBase64Data
        /// The format of the recipe.
        public let recipeOutputFormat: RecipeOutputFormat
        /// A list of key-value pairs that contain metadata for the resource. For more information, see Tag your resources in the IoT Greengrass V2 Developer Guide.
        public let tags: [String: String]?

        @inlinable
        public init(recipe: AWSBase64Data, recipeOutputFormat: RecipeOutputFormat, tags: [String: String]? = nil) {
            self.recipe = recipe
            self.recipeOutputFormat = recipeOutputFormat
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case recipe = "recipe"
            case recipeOutputFormat = "recipeOutputFormat"
            case tags = "tags"
        }
    }

    public struct GetComponentVersionArtifactRequest: AWSEncodableShape {
        /// The ARN of the component version. Specify the ARN of a public or a Lambda component version.
        public let arn: String
        /// The name of the artifact. You can use the GetComponent operation to download the component recipe, which includes the URI of the artifact. The artifact name is the section of the URI after the scheme. For example, in the artifact URI greengrass:SomeArtifact.zip, the artifact name is SomeArtifact.zip.
        public let artifactName: String
        /// Determines if the Amazon S3 URL returned is a FIPS pre-signed URL endpoint.  Specify fips if you want the returned Amazon S3 pre-signed URL to point to  an Amazon S3 FIPS endpoint. If you don't specify a value, the default is standard.
        public let iotEndpointType: IotEndpointType?
        /// Specifies the endpoint to use when getting Amazon S3 pre-signed URLs. All Amazon Web Services Regions except US East (N. Virginia) use REGIONAL in all cases. In the US East (N. Virginia) Region the default is GLOBAL, but you can change it to REGIONAL with this parameter.
        public let s3EndpointType: S3EndpointType?

        @inlinable
        public init(arn: String, artifactName: String, iotEndpointType: IotEndpointType? = nil, s3EndpointType: S3EndpointType? = nil) {
            self.arn = arn
            self.artifactName = artifactName
            self.iotEndpointType = iotEndpointType
            self.s3EndpointType = s3EndpointType
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.arn, key: "arn")
            request.encodePath(self.artifactName, key: "artifactName")
            request.encodeHeader(self.iotEndpointType, key: "x-amz-iot-endpoint-type")
            request.encodeQuery(self.s3EndpointType, key: "s3EndpointType")
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:[^:]*:greengrass:[^:]*:(aws|[0-9]+):components:[^:]+:versions:[^:]+$")
            try self.validate(self.artifactName, name: "artifactName", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetComponentVersionArtifactResponse: AWSDecodableShape {
        /// The URL of the artifact.
        public let preSignedUrl: String

        @inlinable
        public init(preSignedUrl: String) {
            self.preSignedUrl = preSignedUrl
        }

        private enum CodingKeys: String, CodingKey {
            case preSignedUrl = "preSignedUrl"
        }
    }

    public struct GetConnectivityInfoRequest: AWSEncodableShape {
        /// The name of the core device. This is also the name of the IoT thing.
        public let thingName: String

        @inlinable
        public init(thingName: String) {
            self.thingName = thingName
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.thingName, key: "thingName")
        }

        public func validate(name: String) throws {
            try self.validate(self.thingName, name: "thingName", parent: name, max: 128)
            try self.validate(self.thingName, name: "thingName", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetConnectivityInfoResponse: AWSDecodableShape {
        /// The connectivity information for the core device.
        public let connectivityInfo: [ConnectivityInfo]?
        /// A message about the connectivity information request.
        public let message: String?

        @inlinable
        public init(connectivityInfo: [ConnectivityInfo]? = nil, message: String? = nil) {
            self.connectivityInfo = connectivityInfo
            self.message = message
        }

        private enum CodingKeys: String, CodingKey {
            case connectivityInfo = "ConnectivityInfo"
            case message = "Message"
        }
    }

    public struct GetCoreDeviceRequest: AWSEncodableShape {
        /// The name of the core device. This is also the name of the IoT thing.
        public let coreDeviceThingName: String

        @inlinable
        public init(coreDeviceThingName: String) {
            self.coreDeviceThingName = coreDeviceThingName
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.coreDeviceThingName, key: "coreDeviceThingName")
        }

        public func validate(name: String) throws {
            try self.validate(self.coreDeviceThingName, name: "coreDeviceThingName", parent: name, max: 128)
            try self.validate(self.coreDeviceThingName, name: "coreDeviceThingName", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetCoreDeviceResponse: AWSDecodableShape {
        /// The computer architecture of the core device.
        public let architecture: String?
        /// The name of the core device. This is also the name of the IoT thing.
        public let coreDeviceThingName: String?
        /// The version of the IoT Greengrass Core software that the core device runs. This version is equivalent to the version of the Greengrass nucleus component that runs on the core device. For more information, see the Greengrass nucleus component in the IoT Greengrass V2 Developer Guide.
        public let coreVersion: String?
        /// The time at which the core device's status last updated, expressed in ISO 8601 format.
        public let lastStatusUpdateTimestamp: Date?
        /// The operating system platform that the core device runs.
        public let platform: String?
        /// The runtime for the core device. The runtime can be:    aws_nucleus_classic     aws_nucleus_lite
        public let runtime: String?
        /// The status of the core device. The core device status can be:    HEALTHY – The IoT Greengrass Core software and all components run on the core device without issue.    UNHEALTHY – The IoT Greengrass Core software or a component is in a failed state on the core device.
        public let status: CoreDeviceStatus?
        /// A list of key-value pairs that contain metadata for the resource. For more information, see Tag your resources in the IoT Greengrass V2 Developer Guide.
        public let tags: [String: String]?

        @inlinable
        public init(architecture: String? = nil, coreDeviceThingName: String? = nil, coreVersion: String? = nil, lastStatusUpdateTimestamp: Date? = nil, platform: String? = nil, runtime: String? = nil, status: CoreDeviceStatus? = nil, tags: [String: String]? = nil) {
            self.architecture = architecture
            self.coreDeviceThingName = coreDeviceThingName
            self.coreVersion = coreVersion
            self.lastStatusUpdateTimestamp = lastStatusUpdateTimestamp
            self.platform = platform
            self.runtime = runtime
            self.status = status
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case architecture = "architecture"
            case coreDeviceThingName = "coreDeviceThingName"
            case coreVersion = "coreVersion"
            case lastStatusUpdateTimestamp = "lastStatusUpdateTimestamp"
            case platform = "platform"
            case runtime = "runtime"
            case status = "status"
            case tags = "tags"
        }
    }

    public struct GetDeploymentRequest: AWSEncodableShape {
        /// The ID of the deployment.
        public let deploymentId: String

        @inlinable
        public init(deploymentId: String) {
            self.deploymentId = deploymentId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.deploymentId, key: "deploymentId")
        }

        public func validate(name: String) throws {
            try self.validate(self.deploymentId, name: "deploymentId", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetDeploymentResponse: AWSDecodableShape {
        /// The components to deploy. This is a dictionary, where each key is the name of a component, and each key's value is the version and configuration to deploy for that component.
        public let components: [String: ComponentDeploymentSpecification]?
        /// The time at which the deployment was created, expressed in ISO 8601 format.
        public let creationTimestamp: Date?
        /// The ID of the deployment.
        public let deploymentId: String?
        /// The name of the deployment.
        public let deploymentName: String?
        /// The deployment policies for the deployment. These policies define how the deployment updates components and handles failure.
        public let deploymentPolicies: DeploymentPolicies?
        /// The status of the deployment.
        public let deploymentStatus: DeploymentStatus?
        /// The ARN of the IoT job that applies the deployment to target devices.
        public let iotJobArn: String?
        /// The job configuration for the deployment configuration. The job configuration specifies the rollout, timeout, and stop configurations for the deployment configuration.
        public let iotJobConfiguration: DeploymentIoTJobConfiguration?
        /// The ID of the IoT job that applies the deployment to target devices.
        public let iotJobId: String?
        /// Whether or not the deployment is the latest revision for its target.
        public let isLatestForTarget: Bool?
        /// The parent deployment's target ARN within a subdeployment.
        public let parentTargetArn: String?
        /// The revision number of the deployment.
        public let revisionId: String?
        /// A list of key-value pairs that contain metadata for the resource. For more information, see Tag your resources in the IoT Greengrass V2 Developer Guide.
        public let tags: [String: String]?
        /// The ARN of the target IoT thing or thing group.
        public let targetArn: String?

        @inlinable
        public init(components: [String: ComponentDeploymentSpecification]? = nil, creationTimestamp: Date? = nil, deploymentId: String? = nil, deploymentName: String? = nil, deploymentPolicies: DeploymentPolicies? = nil, deploymentStatus: DeploymentStatus? = nil, iotJobArn: String? = nil, iotJobConfiguration: DeploymentIoTJobConfiguration? = nil, iotJobId: String? = nil, isLatestForTarget: Bool? = nil, parentTargetArn: String? = nil, revisionId: String? = nil, tags: [String: String]? = nil, targetArn: String? = nil) {
            self.components = components
            self.creationTimestamp = creationTimestamp
            self.deploymentId = deploymentId
            self.deploymentName = deploymentName
            self.deploymentPolicies = deploymentPolicies
            self.deploymentStatus = deploymentStatus
            self.iotJobArn = iotJobArn
            self.iotJobConfiguration = iotJobConfiguration
            self.iotJobId = iotJobId
            self.isLatestForTarget = isLatestForTarget
            self.parentTargetArn = parentTargetArn
            self.revisionId = revisionId
            self.tags = tags
            self.targetArn = targetArn
        }

        private enum CodingKeys: String, CodingKey {
            case components = "components"
            case creationTimestamp = "creationTimestamp"
            case deploymentId = "deploymentId"
            case deploymentName = "deploymentName"
            case deploymentPolicies = "deploymentPolicies"
            case deploymentStatus = "deploymentStatus"
            case iotJobArn = "iotJobArn"
            case iotJobConfiguration = "iotJobConfiguration"
            case iotJobId = "iotJobId"
            case isLatestForTarget = "isLatestForTarget"
            case parentTargetArn = "parentTargetArn"
            case revisionId = "revisionId"
            case tags = "tags"
            case targetArn = "targetArn"
        }
    }

    public struct GetServiceRoleForAccountRequest: AWSEncodableShape {
        public init() {}
    }

    public struct GetServiceRoleForAccountResponse: AWSDecodableShape {
        /// The time when the service role was associated with IoT Greengrass for your Amazon Web Services account in this Amazon Web Services Region.
        public let associatedAt: String?
        /// The ARN of the service role that is associated with IoT Greengrass for your Amazon Web Services account in this Amazon Web Services Region.
        public let roleArn: String?

        @inlinable
        public init(associatedAt: String? = nil, roleArn: String? = nil) {
            self.associatedAt = associatedAt
            self.roleArn = roleArn
        }

        private enum CodingKeys: String, CodingKey {
            case associatedAt = "AssociatedAt"
            case roleArn = "RoleArn"
        }
    }

    public struct InstalledComponent: AWSDecodableShape {
        /// The name of the component.
        public let componentName: String?
        /// The version of the component.
        public let componentVersion: String?
        /// Whether or not the component is a root component.
        public let isRoot: Bool?
        /// The most recent deployment source that brought the component to the Greengrass core device. For a thing group deployment or thing deployment, the source will be the ID of the last deployment that contained the component. For local deployments it will be LOCAL.  Any deployment will attempt to reinstall currently broken components on the device, which will update the last installation source.
        public let lastInstallationSource: String?
        /// The last time the Greengrass core device sent a message containing a component's state to the Amazon Web Services Cloud. A component does not need to see a state change for this field to update.
        public let lastReportedTimestamp: Date?
        /// The status of how current the data is. This response is based off of component state changes. The status reflects component disruptions and deployments. If a component only sees a configuration update during a deployment, it might not undergo a state change and this status would not be updated.
        public let lastStatusChangeTimestamp: Date?
        /// The lifecycle state of the component.
        public let lifecycleState: InstalledComponentLifecycleState?
        /// A detailed response about the lifecycle state of the component that explains the reason why a component has an error or is broken.
        public let lifecycleStateDetails: String?
        /// The status codes that indicate the reason for failure whenever the lifecycleState has an error or is in a broken state.  Greengrass nucleus v2.8.0 or later is required to get an accurate lifecycleStatusCodes response. This response can be inaccurate in earlier Greengrass nucleus versions.
        public let lifecycleStatusCodes: [String]?

        @inlinable
        public init(componentName: String? = nil, componentVersion: String? = nil, isRoot: Bool? = nil, lastInstallationSource: String? = nil, lastReportedTimestamp: Date? = nil, lastStatusChangeTimestamp: Date? = nil, lifecycleState: InstalledComponentLifecycleState? = nil, lifecycleStateDetails: String? = nil, lifecycleStatusCodes: [String]? = nil) {
            self.componentName = componentName
            self.componentVersion = componentVersion
            self.isRoot = isRoot
            self.lastInstallationSource = lastInstallationSource
            self.lastReportedTimestamp = lastReportedTimestamp
            self.lastStatusChangeTimestamp = lastStatusChangeTimestamp
            self.lifecycleState = lifecycleState
            self.lifecycleStateDetails = lifecycleStateDetails
            self.lifecycleStatusCodes = lifecycleStatusCodes
        }

        private enum CodingKeys: String, CodingKey {
            case componentName = "componentName"
            case componentVersion = "componentVersion"
            case isRoot = "isRoot"
            case lastInstallationSource = "lastInstallationSource"
            case lastReportedTimestamp = "lastReportedTimestamp"
            case lastStatusChangeTimestamp = "lastStatusChangeTimestamp"
            case lifecycleState = "lifecycleState"
            case lifecycleStateDetails = "lifecycleStateDetails"
            case lifecycleStatusCodes = "lifecycleStatusCodes"
        }
    }

    public struct InternalServerException: AWSErrorShape {
        public let message: String
        /// The amount of time to wait before you retry the request.
        public let retryAfterSeconds: Int?

        @inlinable
        public init(message: String, retryAfterSeconds: Int? = nil) {
            self.message = message
            self.retryAfterSeconds = retryAfterSeconds
        }

        public init(from decoder: Decoder) throws {
            let response = decoder.userInfo[.awsResponse]! as! ResponseDecodingContainer
            let container = try decoder.container(keyedBy: CodingKeys.self)
            self.message = try container.decode(String.self, forKey: .message)
            self.retryAfterSeconds = try response.decodeHeaderIfPresent(Int.self, key: "Retry-After")
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
        }
    }

    public struct IoTJobAbortConfig: AWSEncodableShape & AWSDecodableShape {
        /// The list of criteria that define when and how to cancel the configuration deployment.
        public let criteriaList: [IoTJobAbortCriteria]

        @inlinable
        public init(criteriaList: [IoTJobAbortCriteria]) {
            self.criteriaList = criteriaList
        }

        public func validate(name: String) throws {
            try self.criteriaList.forEach {
                try $0.validate(name: "\(name).criteriaList[]")
            }
            try self.validate(self.criteriaList, name: "criteriaList", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case criteriaList = "criteriaList"
        }
    }

    public struct IoTJobAbortCriteria: AWSEncodableShape & AWSDecodableShape {
        /// The action to perform when the criteria are met.
        public let action: IoTJobAbortAction
        /// The type of job deployment failure that can cancel a job.
        public let failureType: IoTJobExecutionFailureType
        /// The minimum number of things that receive the configuration before the job can cancel.
        public let minNumberOfExecutedThings: Int
        /// The minimum percentage of failureType failures that occur before the job can cancel. This parameter supports up to two digits after the decimal (for example, you can specify 10.9 or 10.99, but not 10.999).
        public let thresholdPercentage: Double

        @inlinable
        public init(action: IoTJobAbortAction, failureType: IoTJobExecutionFailureType, minNumberOfExecutedThings: Int, thresholdPercentage: Double) {
            self.action = action
            self.failureType = failureType
            self.minNumberOfExecutedThings = minNumberOfExecutedThings
            self.thresholdPercentage = thresholdPercentage
        }

        public func validate(name: String) throws {
            try self.validate(self.minNumberOfExecutedThings, name: "minNumberOfExecutedThings", parent: name, min: 1)
            try self.validate(self.thresholdPercentage, name: "thresholdPercentage", parent: name, max: 100.0)
        }

        private enum CodingKeys: String, CodingKey {
            case action = "action"
            case failureType = "failureType"
            case minNumberOfExecutedThings = "minNumberOfExecutedThings"
            case thresholdPercentage = "thresholdPercentage"
        }
    }

    public struct IoTJobExecutionsRolloutConfig: AWSEncodableShape & AWSDecodableShape {
        /// The exponential rate to increase the job rollout rate.
        public let exponentialRate: IoTJobExponentialRolloutRate?
        /// The maximum number of devices that receive a pending job notification, per minute.
        public let maximumPerMinute: Int?

        @inlinable
        public init(exponentialRate: IoTJobExponentialRolloutRate? = nil, maximumPerMinute: Int? = nil) {
            self.exponentialRate = exponentialRate
            self.maximumPerMinute = maximumPerMinute
        }

        public func validate(name: String) throws {
            try self.exponentialRate?.validate(name: "\(name).exponentialRate")
            try self.validate(self.maximumPerMinute, name: "maximumPerMinute", parent: name, max: 1000)
            try self.validate(self.maximumPerMinute, name: "maximumPerMinute", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case exponentialRate = "exponentialRate"
            case maximumPerMinute = "maximumPerMinute"
        }
    }

    public struct IoTJobExponentialRolloutRate: AWSEncodableShape & AWSDecodableShape {
        /// The minimum number of devices that receive a pending job notification, per minute, when the job starts. This parameter defines the initial rollout rate of the job.
        public let baseRatePerMinute: Int
        /// The exponential factor to increase the rollout rate for the job. This parameter supports up to one digit after the decimal (for example, you can specify 1.5, but not 1.55).
        public let incrementFactor: Double
        /// The criteria to increase the rollout rate for the job.
        public let rateIncreaseCriteria: IoTJobRateIncreaseCriteria

        @inlinable
        public init(baseRatePerMinute: Int, incrementFactor: Double, rateIncreaseCriteria: IoTJobRateIncreaseCriteria) {
            self.baseRatePerMinute = baseRatePerMinute
            self.incrementFactor = incrementFactor
            self.rateIncreaseCriteria = rateIncreaseCriteria
        }

        public func validate(name: String) throws {
            try self.validate(self.baseRatePerMinute, name: "baseRatePerMinute", parent: name, max: 1000)
            try self.validate(self.baseRatePerMinute, name: "baseRatePerMinute", parent: name, min: 1)
            try self.validate(self.incrementFactor, name: "incrementFactor", parent: name, max: 5.0)
            try self.validate(self.incrementFactor, name: "incrementFactor", parent: name, min: 1.0)
            try self.rateIncreaseCriteria.validate(name: "\(name).rateIncreaseCriteria")
        }

        private enum CodingKeys: String, CodingKey {
            case baseRatePerMinute = "baseRatePerMinute"
            case incrementFactor = "incrementFactor"
            case rateIncreaseCriteria = "rateIncreaseCriteria"
        }
    }

    public struct IoTJobRateIncreaseCriteria: AWSEncodableShape & AWSDecodableShape {
        /// The number of devices to receive the job notification before the rollout rate increases.
        public let numberOfNotifiedThings: Int?
        /// The number of devices to successfully run the configuration job before the rollout rate increases.
        public let numberOfSucceededThings: Int?

        @inlinable
        public init(numberOfNotifiedThings: Int? = nil, numberOfSucceededThings: Int? = nil) {
            self.numberOfNotifiedThings = numberOfNotifiedThings
            self.numberOfSucceededThings = numberOfSucceededThings
        }

        public func validate(name: String) throws {
            try self.validate(self.numberOfNotifiedThings, name: "numberOfNotifiedThings", parent: name, min: 1)
            try self.validate(self.numberOfSucceededThings, name: "numberOfSucceededThings", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case numberOfNotifiedThings = "numberOfNotifiedThings"
            case numberOfSucceededThings = "numberOfSucceededThings"
        }
    }

    public struct IoTJobTimeoutConfig: AWSEncodableShape & AWSDecodableShape {
        /// The amount of time, in minutes, that devices have to complete the job. The timer starts when the job status is set to IN_PROGRESS. If the job status doesn't change to a terminal state before the time expires, then the job status is set to TIMED_OUT. The timeout interval must be between 1 minute and 7 days (10080 minutes).
        public let inProgressTimeoutInMinutes: Int64?

        @inlinable
        public init(inProgressTimeoutInMinutes: Int64? = nil) {
            self.inProgressTimeoutInMinutes = inProgressTimeoutInMinutes
        }

        private enum CodingKeys: String, CodingKey {
            case inProgressTimeoutInMinutes = "inProgressTimeoutInMinutes"
        }
    }

    public struct LambdaContainerParams: AWSEncodableShape {
        /// The list of system devices that the container can access.
        public let devices: [LambdaDeviceMount]?
        /// The memory size of the container, expressed in kilobytes. Default: 16384 (16 MB)
        public let memorySizeInKB: Int?
        /// Whether or not the container can read information from the device's /sys folder. Default: false
        public let mountROSysfs: Bool?
        /// The list of volumes that the container can access.
        public let volumes: [LambdaVolumeMount]?

        @inlinable
        public init(devices: [LambdaDeviceMount]? = nil, memorySizeInKB: Int? = nil, mountROSysfs: Bool? = nil, volumes: [LambdaVolumeMount]? = nil) {
            self.devices = devices
            self.memorySizeInKB = memorySizeInKB
            self.mountROSysfs = mountROSysfs
            self.volumes = volumes
        }

        private enum CodingKeys: String, CodingKey {
            case devices = "devices"
            case memorySizeInKB = "memorySizeInKB"
            case mountROSysfs = "mountROSysfs"
            case volumes = "volumes"
        }
    }

    public struct LambdaDeviceMount: AWSEncodableShape {
        /// Whether or not to add the component's system user as an owner of the device. Default: false
        public let addGroupOwner: Bool?
        /// The mount path for the device in the file system.
        public let path: String
        /// The permission to access the device: read/only (ro) or read/write (rw). Default: ro
        public let permission: LambdaFilesystemPermission?

        @inlinable
        public init(addGroupOwner: Bool? = nil, path: String, permission: LambdaFilesystemPermission? = nil) {
            self.addGroupOwner = addGroupOwner
            self.path = path
            self.permission = permission
        }

        private enum CodingKeys: String, CodingKey {
            case addGroupOwner = "addGroupOwner"
            case path = "path"
            case permission = "permission"
        }
    }

    public struct LambdaEventSource: AWSEncodableShape {
        /// The topic to which to subscribe to receive event messages.
        public let topic: String
        /// The type of event source. Choose from the following options:    PUB_SUB – Subscribe to local publish/subscribe messages. This event source type doesn't support MQTT wildcards (+ and #) in the event source topic.    IOT_CORE – Subscribe to Amazon Web Services IoT Core MQTT messages. This event source type supports MQTT wildcards (+ and #) in the event source topic.
        public let type: LambdaEventSourceType

        @inlinable
        public init(topic: String, type: LambdaEventSourceType) {
            self.topic = topic
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case topic = "topic"
            case type = "type"
        }
    }

    public struct LambdaExecutionParameters: AWSEncodableShape {
        /// The map of environment variables that are available to the Lambda function when it runs.
        public let environmentVariables: [String: String]?
        /// The list of event sources to which to subscribe to receive work messages. The Lambda function runs when it receives a message from an event source. You can subscribe this function to local publish/subscribe messages and Amazon Web Services IoT Core MQTT messages.
        public let eventSources: [LambdaEventSource]?
        /// The list of arguments to pass to the Lambda function when it runs.
        public let execArgs: [String]?
        /// The encoding type that the Lambda function supports. Default: json
        public let inputPayloadEncodingType: LambdaInputPayloadEncodingType?
        /// The parameters for the Linux process that contains the Lambda function.
        public let linuxProcessParams: LambdaLinuxProcessParams?
        /// The maximum amount of time in seconds that a non-pinned Lambda function can idle before the IoT Greengrass Core software stops its process.
        public let maxIdleTimeInSeconds: Int?
        /// The maximum number of instances that a non-pinned Lambda function can run at the same time.
        public let maxInstancesCount: Int?
        /// The maximum size of the message queue for the Lambda function component. The IoT Greengrass core stores messages in a FIFO (first-in-first-out) queue until it can run the Lambda function to consume each message.
        public let maxQueueSize: Int?
        /// Whether or not the Lambda function is pinned, or long-lived.   A pinned Lambda function starts when IoT Greengrass starts and keeps running in its own container.   A non-pinned Lambda function starts only when it receives a work item and exists after it idles for maxIdleTimeInSeconds. If the function has multiple work items, the IoT Greengrass Core software creates multiple instances of the function.   Default: true
        public let pinned: Bool?
        /// The interval in seconds at which a pinned (also known as long-lived) Lambda function component sends status updates to the Lambda manager component.
        public let statusTimeoutInSeconds: Int?
        /// The maximum amount of time in seconds that the Lambda function can process a work item.
        public let timeoutInSeconds: Int?

        @inlinable
        public init(environmentVariables: [String: String]? = nil, eventSources: [LambdaEventSource]? = nil, execArgs: [String]? = nil, inputPayloadEncodingType: LambdaInputPayloadEncodingType? = nil, linuxProcessParams: LambdaLinuxProcessParams? = nil, maxIdleTimeInSeconds: Int? = nil, maxInstancesCount: Int? = nil, maxQueueSize: Int? = nil, pinned: Bool? = nil, statusTimeoutInSeconds: Int? = nil, timeoutInSeconds: Int? = nil) {
            self.environmentVariables = environmentVariables
            self.eventSources = eventSources
            self.execArgs = execArgs
            self.inputPayloadEncodingType = inputPayloadEncodingType
            self.linuxProcessParams = linuxProcessParams
            self.maxIdleTimeInSeconds = maxIdleTimeInSeconds
            self.maxInstancesCount = maxInstancesCount
            self.maxQueueSize = maxQueueSize
            self.pinned = pinned
            self.statusTimeoutInSeconds = statusTimeoutInSeconds
            self.timeoutInSeconds = timeoutInSeconds
        }

        public func validate(name: String) throws {
            try self.environmentVariables?.forEach {
                try validate($0.key, name: "environmentVariables.key", parent: name, min: 1)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case environmentVariables = "environmentVariables"
            case eventSources = "eventSources"
            case execArgs = "execArgs"
            case inputPayloadEncodingType = "inputPayloadEncodingType"
            case linuxProcessParams = "linuxProcessParams"
            case maxIdleTimeInSeconds = "maxIdleTimeInSeconds"
            case maxInstancesCount = "maxInstancesCount"
            case maxQueueSize = "maxQueueSize"
            case pinned = "pinned"
            case statusTimeoutInSeconds = "statusTimeoutInSeconds"
            case timeoutInSeconds = "timeoutInSeconds"
        }
    }

    public struct LambdaFunctionRecipeSource: AWSEncodableShape {
        /// The component versions on which this Lambda function component depends.
        public let componentDependencies: [String: ComponentDependencyRequirement]?
        /// The system and runtime parameters for the Lambda function as it runs on the Greengrass core device.
        public let componentLambdaParameters: LambdaExecutionParameters?
        /// The name of the component. Defaults to the name of the Lambda function.
        public let componentName: String?
        /// The platforms that the component version supports.
        public let componentPlatforms: [ComponentPlatform]?
        /// The version of the component. Defaults to the version of the Lambda function as a semantic version. For example, if your function version is 3, the component version becomes 3.0.0.
        public let componentVersion: String?
        /// The ARN of the Lambda function. The ARN must include the version of the function to import. You can't use version aliases like $LATEST.
        public let lambdaArn: String

        @inlinable
        public init(componentDependencies: [String: ComponentDependencyRequirement]? = nil, componentLambdaParameters: LambdaExecutionParameters? = nil, componentName: String? = nil, componentPlatforms: [ComponentPlatform]? = nil, componentVersion: String? = nil, lambdaArn: String) {
            self.componentDependencies = componentDependencies
            self.componentLambdaParameters = componentLambdaParameters
            self.componentName = componentName
            self.componentPlatforms = componentPlatforms
            self.componentVersion = componentVersion
            self.lambdaArn = lambdaArn
        }

        public func validate(name: String) throws {
            try self.componentDependencies?.forEach {
                try validate($0.key, name: "componentDependencies.key", parent: name, min: 1)
                try $0.value.validate(name: "\(name).componentDependencies[\"\($0.key)\"]")
            }
            try self.componentLambdaParameters?.validate(name: "\(name).componentLambdaParameters")
            try self.validate(self.componentName, name: "componentName", parent: name, max: 128)
            try self.validate(self.componentName, name: "componentName", parent: name, min: 1)
            try self.componentPlatforms?.forEach {
                try $0.validate(name: "\(name).componentPlatforms[]")
            }
            try self.validate(self.componentVersion, name: "componentVersion", parent: name, max: 64)
            try self.validate(self.componentVersion, name: "componentVersion", parent: name, min: 1)
            try self.validate(self.lambdaArn, name: "lambdaArn", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case componentDependencies = "componentDependencies"
            case componentLambdaParameters = "componentLambdaParameters"
            case componentName = "componentName"
            case componentPlatforms = "componentPlatforms"
            case componentVersion = "componentVersion"
            case lambdaArn = "lambdaArn"
        }
    }

    public struct LambdaLinuxProcessParams: AWSEncodableShape {
        /// The parameters for the container in which the Lambda function runs.
        public let containerParams: LambdaContainerParams?
        /// The isolation mode for the process that contains the Lambda function. The process can run in an isolated runtime environment inside the IoT Greengrass container, or as a regular process outside any container. Default: GreengrassContainer
        public let isolationMode: LambdaIsolationMode?

        @inlinable
        public init(containerParams: LambdaContainerParams? = nil, isolationMode: LambdaIsolationMode? = nil) {
            self.containerParams = containerParams
            self.isolationMode = isolationMode
        }

        private enum CodingKeys: String, CodingKey {
            case containerParams = "containerParams"
            case isolationMode = "isolationMode"
        }
    }

    public struct LambdaVolumeMount: AWSEncodableShape {
        /// Whether or not to add the IoT Greengrass user group as an owner of the volume. Default: false
        public let addGroupOwner: Bool?
        /// The path to the logical volume in the file system.
        public let destinationPath: String
        /// The permission to access the volume: read/only (ro) or read/write (rw). Default: ro
        public let permission: LambdaFilesystemPermission?
        /// The path to the physical volume in the file system.
        public let sourcePath: String

        @inlinable
        public init(addGroupOwner: Bool? = nil, destinationPath: String, permission: LambdaFilesystemPermission? = nil, sourcePath: String) {
            self.addGroupOwner = addGroupOwner
            self.destinationPath = destinationPath
            self.permission = permission
            self.sourcePath = sourcePath
        }

        private enum CodingKeys: String, CodingKey {
            case addGroupOwner = "addGroupOwner"
            case destinationPath = "destinationPath"
            case permission = "permission"
            case sourcePath = "sourcePath"
        }
    }

    public struct ListClientDevicesAssociatedWithCoreDeviceRequest: AWSEncodableShape {
        /// The name of the core device. This is also the name of the IoT thing.
        public let coreDeviceThingName: String
        /// The maximum number of results to be returned per paginated request.
        public let maxResults: Int?
        /// The token to be used for the next set of paginated results.
        public let nextToken: String?

        @inlinable
        public init(coreDeviceThingName: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.coreDeviceThingName = coreDeviceThingName
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.coreDeviceThingName, key: "coreDeviceThingName")
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
        }

        public func validate(name: String) throws {
            try self.validate(self.coreDeviceThingName, name: "coreDeviceThingName", parent: name, max: 128)
            try self.validate(self.coreDeviceThingName, name: "coreDeviceThingName", parent: name, min: 1)
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListClientDevicesAssociatedWithCoreDeviceResponse: AWSDecodableShape {
        /// A list that describes the client devices that are associated with the core device.
        public let associatedClientDevices: [AssociatedClientDevice]?
        /// The token for the next set of results, or null if there are no additional results.
        public let nextToken: String?

        @inlinable
        public init(associatedClientDevices: [AssociatedClientDevice]? = nil, nextToken: String? = nil) {
            self.associatedClientDevices = associatedClientDevices
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case associatedClientDevices = "associatedClientDevices"
            case nextToken = "nextToken"
        }
    }

    public struct ListComponentVersionsRequest: AWSEncodableShape {
        /// The ARN of the component.
        public let arn: String
        /// The maximum number of results to be returned per paginated request.
        public let maxResults: Int?
        /// The token to be used for the next set of paginated results.
        public let nextToken: String?

        @inlinable
        public init(arn: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.arn = arn
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.arn, key: "arn")
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:[^:]*:greengrass:[^:]*:(aws|[0-9]+):components:[^:]+$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListComponentVersionsResponse: AWSDecodableShape {
        /// A list of versions that exist for the component.
        public let componentVersions: [ComponentVersionListItem]?
        /// The token for the next set of results, or null if there are no additional results.
        public let nextToken: String?

        @inlinable
        public init(componentVersions: [ComponentVersionListItem]? = nil, nextToken: String? = nil) {
            self.componentVersions = componentVersions
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case componentVersions = "componentVersions"
            case nextToken = "nextToken"
        }
    }

    public struct ListComponentsRequest: AWSEncodableShape {
        /// The maximum number of results to be returned per paginated request.
        public let maxResults: Int?
        /// The token to be used for the next set of paginated results.
        public let nextToken: String?
        /// The scope of the components to list. Default: PRIVATE
        public let scope: ComponentVisibilityScope?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil, scope: ComponentVisibilityScope? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.scope = scope
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
            request.encodeQuery(self.scope, key: "scope")
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListComponentsResponse: AWSDecodableShape {
        /// A list that summarizes each component.
        public let components: [Component]?
        /// The token for the next set of results, or null if there are no additional results.
        public let nextToken: String?

        @inlinable
        public init(components: [Component]? = nil, nextToken: String? = nil) {
            self.components = components
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case components = "components"
            case nextToken = "nextToken"
        }
    }

    public struct ListCoreDevicesRequest: AWSEncodableShape {
        /// The maximum number of results to be returned per paginated request.
        public let maxResults: Int?
        /// The token to be used for the next set of paginated results.
        public let nextToken: String?
        /// The runtime to be used by the core device. The runtime can be:    aws_nucleus_classic     aws_nucleus_lite
        public let runtime: String?
        /// The core device status by which to filter. If you specify this parameter, the list includes only core devices that have this status. Choose one of the following options:    HEALTHY – The IoT Greengrass Core software and all components run on the core device without issue.    UNHEALTHY – The IoT Greengrass Core software or a component is in a failed state on the core device.
        public let status: CoreDeviceStatus?
        /// The ARN of the IoT thing group by which to filter. If you specify this parameter, the list includes only core devices that have successfully deployed a deployment that targets the thing group. When you remove a core device from a thing group, the list continues to include that core device.
        public let thingGroupArn: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil, runtime: String? = nil, status: CoreDeviceStatus? = nil, thingGroupArn: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.runtime = runtime
            self.status = status
            self.thingGroupArn = thingGroupArn
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
            request.encodeQuery(self.runtime, key: "runtime")
            request.encodeQuery(self.status, key: "status")
            request.encodeQuery(self.thingGroupArn, key: "thingGroupArn")
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.runtime, name: "runtime", parent: name, max: 255)
            try self.validate(self.runtime, name: "runtime", parent: name, min: 1)
            try self.validate(self.thingGroupArn, name: "thingGroupArn", parent: name, pattern: "^arn:[^:]*:iot:[^:]*:[0-9]+:thinggroup/.+$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListCoreDevicesResponse: AWSDecodableShape {
        /// A list that summarizes each core device.
        public let coreDevices: [CoreDevice]?
        /// The token for the next set of results, or null if there are no additional results.
        public let nextToken: String?

        @inlinable
        public init(coreDevices: [CoreDevice]? = nil, nextToken: String? = nil) {
            self.coreDevices = coreDevices
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case coreDevices = "coreDevices"
            case nextToken = "nextToken"
        }
    }

    public struct ListDeploymentsRequest: AWSEncodableShape {
        /// The filter for the list of deployments. Choose one of the following options:    ALL – The list includes all deployments.    LATEST_ONLY – The list includes only the latest revision of each deployment.   Default: LATEST_ONLY
        public let historyFilter: DeploymentHistoryFilter?
        /// The maximum number of results to be returned per paginated request. Default: 50
        public let maxResults: Int?
        /// The token to be used for the next set of paginated results.
        public let nextToken: String?
        /// The parent deployment's target ARN within a subdeployment.
        public let parentTargetArn: String?
        /// The ARN of the target IoT thing or thing group.
        public let targetArn: String?

        @inlinable
        public init(historyFilter: DeploymentHistoryFilter? = nil, maxResults: Int? = nil, nextToken: String? = nil, parentTargetArn: String? = nil, targetArn: String? = nil) {
            self.historyFilter = historyFilter
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.parentTargetArn = parentTargetArn
            self.targetArn = targetArn
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.historyFilter, key: "historyFilter")
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
            request.encodeQuery(self.parentTargetArn, key: "parentTargetArn")
            request.encodeQuery(self.targetArn, key: "targetArn")
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.parentTargetArn, name: "parentTargetArn", parent: name, pattern: "^arn:[^:]*:iot:[^:]*:[0-9]+:thinggroup/.+$")
            try self.validate(self.targetArn, name: "targetArn", parent: name, pattern: "^arn:[^:]*:iot:[^:]*:[0-9]+:(thing|thinggroup)/.+$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListDeploymentsResponse: AWSDecodableShape {
        /// A list that summarizes each deployment.
        public let deployments: [Deployment]?
        /// The token for the next set of results, or null if there are no additional results.
        public let nextToken: String?

        @inlinable
        public init(deployments: [Deployment]? = nil, nextToken: String? = nil) {
            self.deployments = deployments
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case deployments = "deployments"
            case nextToken = "nextToken"
        }
    }

    public struct ListEffectiveDeploymentsRequest: AWSEncodableShape {
        /// The name of the core device. This is also the name of the IoT thing.
        public let coreDeviceThingName: String
        /// The maximum number of results to be returned per paginated request.
        public let maxResults: Int?
        /// The token to be used for the next set of paginated results.
        public let nextToken: String?

        @inlinable
        public init(coreDeviceThingName: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.coreDeviceThingName = coreDeviceThingName
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.coreDeviceThingName, key: "coreDeviceThingName")
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
        }

        public func validate(name: String) throws {
            try self.validate(self.coreDeviceThingName, name: "coreDeviceThingName", parent: name, max: 128)
            try self.validate(self.coreDeviceThingName, name: "coreDeviceThingName", parent: name, min: 1)
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListEffectiveDeploymentsResponse: AWSDecodableShape {
        /// A list that summarizes each deployment on the core device.
        public let effectiveDeployments: [EffectiveDeployment]?
        /// The token for the next set of results, or null if there are no additional results.
        public let nextToken: String?

        @inlinable
        public init(effectiveDeployments: [EffectiveDeployment]? = nil, nextToken: String? = nil) {
            self.effectiveDeployments = effectiveDeployments
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case effectiveDeployments = "effectiveDeployments"
            case nextToken = "nextToken"
        }
    }

    public struct ListInstalledComponentsRequest: AWSEncodableShape {
        /// The name of the core device. This is also the name of the IoT thing.
        public let coreDeviceThingName: String
        /// The maximum number of results to be returned per paginated request.
        public let maxResults: Int?
        /// The token to be used for the next set of paginated results.
        public let nextToken: String?
        /// The filter for the list of components. Choose from the following options:    ALL – The list includes all components installed on the core device.    ROOT – The list includes only root components, which are components that you specify in a deployment. When you choose this option, the list doesn't include components that the core device installs as dependencies of other components.   Default: ROOT
        public let topologyFilter: InstalledComponentTopologyFilter?

        @inlinable
        public init(coreDeviceThingName: String, maxResults: Int? = nil, nextToken: String? = nil, topologyFilter: InstalledComponentTopologyFilter? = nil) {
            self.coreDeviceThingName = coreDeviceThingName
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.topologyFilter = topologyFilter
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.coreDeviceThingName, key: "coreDeviceThingName")
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
            request.encodeQuery(self.topologyFilter, key: "topologyFilter")
        }

        public func validate(name: String) throws {
            try self.validate(self.coreDeviceThingName, name: "coreDeviceThingName", parent: name, max: 128)
            try self.validate(self.coreDeviceThingName, name: "coreDeviceThingName", parent: name, min: 1)
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListInstalledComponentsResponse: AWSDecodableShape {
        /// A list that summarizes each component on the core device.  Greengrass nucleus v2.7.0 or later is required to get an accurate lastStatusChangeTimestamp response. This response can be inaccurate in earlier Greengrass nucleus versions.   Greengrass nucleus v2.8.0 or later is required to get an accurate lastInstallationSource and lastReportedTimestamp response. This response can be inaccurate or null in earlier Greengrass nucleus versions.
        public let installedComponents: [InstalledComponent]?
        /// The token for the next set of results, or null if there are no additional results.
        public let nextToken: String?

        @inlinable
        public init(installedComponents: [InstalledComponent]? = nil, nextToken: String? = nil) {
            self.installedComponents = installedComponents
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case installedComponents = "installedComponents"
            case nextToken = "nextToken"
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        /// The ARN of the resource.
        public let resourceArn: String

        @inlinable
        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "resourceArn")
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:[^:]*:greengrass:[^:]*:(aws|[0-9]+):(components|deployments|coreDevices):")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// A list of key-value pairs that contain metadata for the resource. For more information, see Tag your resources in the IoT Greengrass V2 Developer Guide.
        public let tags: [String: String]?

        @inlinable
        public init(tags: [String: String]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "tags"
        }
    }

    public struct ResolveComponentCandidatesRequest: AWSEncodableShape {
        /// The list of components to resolve.
        public let componentCandidates: [ComponentCandidate]?
        /// The platform to use to resolve compatible components.
        public let platform: ComponentPlatform?

        @inlinable
        public init(componentCandidates: [ComponentCandidate]? = nil, platform: ComponentPlatform? = nil) {
            self.componentCandidates = componentCandidates
            self.platform = platform
        }

        public func validate(name: String) throws {
            try self.componentCandidates?.forEach {
                try $0.validate(name: "\(name).componentCandidates[]")
            }
            try self.platform?.validate(name: "\(name).platform")
        }

        private enum CodingKeys: String, CodingKey {
            case componentCandidates = "componentCandidates"
            case platform = "platform"
        }
    }

    public struct ResolveComponentCandidatesResponse: AWSDecodableShape {
        /// A list of components that meet the requirements that you specify in the request. This list includes each component's recipe that you can use to install the component.
        public let resolvedComponentVersions: [ResolvedComponentVersion]?

        @inlinable
        public init(resolvedComponentVersions: [ResolvedComponentVersion]? = nil) {
            self.resolvedComponentVersions = resolvedComponentVersions
        }

        private enum CodingKeys: String, CodingKey {
            case resolvedComponentVersions = "resolvedComponentVersions"
        }
    }

    public struct ResolvedComponentVersion: AWSDecodableShape {
        /// The ARN of the component version.
        public let arn: String?
        /// The name of the component.
        public let componentName: String?
        /// The version of the component.
        public let componentVersion: String?
        /// A message that communicates details about the vendor guidance state of the component version. This message communicates why a component version is discontinued or deleted.
        public let message: String?
        /// The recipe of the component version.
        public let recipe: AWSBase64Data?
        /// The vendor guidance state for the component version. This state indicates whether the component version has any issues that you should consider before you deploy it. The vendor guidance state can be:    ACTIVE – This component version is available and recommended for use.    DISCONTINUED – This component version has been discontinued by its publisher. You can deploy this component version, but we recommend that you use a different version of this component.    DELETED – This component version has been deleted by its publisher, so you can't deploy it. If you have any existing deployments that specify this component version, those deployments will fail.
        public let vendorGuidance: VendorGuidance?

        @inlinable
        public init(arn: String? = nil, componentName: String? = nil, componentVersion: String? = nil, message: String? = nil, recipe: AWSBase64Data? = nil, vendorGuidance: VendorGuidance? = nil) {
            self.arn = arn
            self.componentName = componentName
            self.componentVersion = componentVersion
            self.message = message
            self.recipe = recipe
            self.vendorGuidance = vendorGuidance
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case componentName = "componentName"
            case componentVersion = "componentVersion"
            case message = "message"
            case recipe = "recipe"
            case vendorGuidance = "vendorGuidance"
        }
    }

    public struct ResourceNotFoundException: AWSErrorShape {
        public let message: String
        /// The ID of the resource that isn't found.
        public let resourceId: String
        /// The type of the resource that isn't found.
        public let resourceType: String

        @inlinable
        public init(message: String, resourceId: String, resourceType: String) {
            self.message = message
            self.resourceId = resourceId
            self.resourceType = resourceType
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case resourceId = "resourceId"
            case resourceType = "resourceType"
        }
    }

    public struct ServiceQuotaExceededException: AWSErrorShape {
        public let message: String
        /// The code for the quota in Service Quotas.
        public let quotaCode: String
        /// The ID of the resource that exceeds the service quota.
        public let resourceId: String?
        /// The type of the resource that exceeds the service quota.
        public let resourceType: String?
        /// The code for the service in Service Quotas.
        public let serviceCode: String

        @inlinable
        public init(message: String, quotaCode: String, resourceId: String? = nil, resourceType: String? = nil, serviceCode: String) {
            self.message = message
            self.quotaCode = quotaCode
            self.resourceId = resourceId
            self.resourceType = resourceType
            self.serviceCode = serviceCode
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case quotaCode = "quotaCode"
            case resourceId = "resourceId"
            case resourceType = "resourceType"
            case serviceCode = "serviceCode"
        }
    }

    public struct SystemResourceLimits: AWSEncodableShape & AWSDecodableShape {
        /// The maximum amount of CPU time that a component's processes can use on the core device. A core device's total CPU time is equivalent to the device's number of CPU cores. For example, on a core device with 4 CPU cores, you can set this value to 2 to limit the component's processes to 50 percent usage of each CPU core. On a device with 1 CPU core, you can set this value to 0.25 to limit the component's processes to 25 percent usage of the CPU. If you set this value to a number greater than the number of CPU cores, the IoT Greengrass Core software doesn't limit the component's CPU usage.
        public let cpus: Double?
        /// The maximum amount of RAM, expressed in kilobytes, that a component's processes can use on the core device.
        public let memory: Int64?

        @inlinable
        public init(cpus: Double? = nil, memory: Int64? = nil) {
            self.cpus = cpus
            self.memory = memory
        }

        public func validate(name: String) throws {
            try self.validate(self.cpus, name: "cpus", parent: name, min: 0.0)
            try self.validate(self.memory, name: "memory", parent: name, max: 9223372036854771712)
            try self.validate(self.memory, name: "memory", parent: name, min: 0)
        }

        private enum CodingKeys: String, CodingKey {
            case cpus = "cpus"
            case memory = "memory"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        /// The ARN of the resource to tag.
        public let resourceArn: String
        /// A list of key-value pairs that contain metadata for the resource. For more information, see Tag your resources in the IoT Greengrass V2 Developer Guide.
        public let tags: [String: String]

        @inlinable
        public init(resourceArn: String, tags: [String: String]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "resourceArn")
            try container.encode(self.tags, forKey: .tags)
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:[^:]*:greengrass:[^:]*:(aws|[0-9]+):(components|deployments|coreDevices):")
            try self.tags.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "tags"
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct ThrottlingException: AWSErrorShape {
        public let message: String
        /// The code for the quota in Service Quotas.
        public let quotaCode: String?
        /// The amount of time to wait before you retry the request.
        public let retryAfterSeconds: Int?
        /// The code for the service in Service Quotas.
        public let serviceCode: String?

        @inlinable
        public init(message: String, quotaCode: String? = nil, retryAfterSeconds: Int? = nil, serviceCode: String? = nil) {
            self.message = message
            self.quotaCode = quotaCode
            self.retryAfterSeconds = retryAfterSeconds
            self.serviceCode = serviceCode
        }

        public init(from decoder: Decoder) throws {
            let response = decoder.userInfo[.awsResponse]! as! ResponseDecodingContainer
            let container = try decoder.container(keyedBy: CodingKeys.self)
            self.message = try container.decode(String.self, forKey: .message)
            self.quotaCode = try container.decodeIfPresent(String.self, forKey: .quotaCode)
            self.retryAfterSeconds = try response.decodeHeaderIfPresent(Int.self, key: "Retry-After")
            self.serviceCode = try container.decodeIfPresent(String.self, forKey: .serviceCode)
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case quotaCode = "quotaCode"
            case serviceCode = "serviceCode"
        }
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        /// The ARN of the resource to untag.
        public let resourceArn: String
        /// A list of keys for tags to remove from the resource.
        public let tagKeys: [String]

        @inlinable
        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "resourceArn")
            request.encodeQuery(self.tagKeys, key: "tagKeys")
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:[^:]*:greengrass:[^:]*:(aws|[0-9]+):(components|deployments|coreDevices):")
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
            }
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, max: 200)
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateConnectivityInfoRequest: AWSEncodableShape {
        /// The connectivity information for the core device.
        public let connectivityInfo: [ConnectivityInfo]
        /// The name of the core device. This is also the name of the IoT thing.
        public let thingName: String

        @inlinable
        public init(connectivityInfo: [ConnectivityInfo], thingName: String) {
            self.connectivityInfo = connectivityInfo
            self.thingName = thingName
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encode(self.connectivityInfo, forKey: .connectivityInfo)
            request.encodePath(self.thingName, key: "ThingName")
        }

        public func validate(name: String) throws {
            try self.connectivityInfo.forEach {
                try $0.validate(name: "\(name).connectivityInfo[]")
            }
            try self.validate(self.thingName, name: "thingName", parent: name, max: 128)
            try self.validate(self.thingName, name: "thingName", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case connectivityInfo = "ConnectivityInfo"
        }
    }

    public struct UpdateConnectivityInfoResponse: AWSDecodableShape {
        /// A message about the connectivity information update request.
        public let message: String?
        /// The new version of the connectivity information for the core device.
        public let version: String?

        @inlinable
        public init(message: String? = nil, version: String? = nil) {
            self.message = message
            self.version = version
        }

        private enum CodingKeys: String, CodingKey {
            case message = "Message"
            case version = "Version"
        }
    }

    public struct ValidationException: AWSErrorShape {
        /// The list of fields that failed to validate.
        public let fields: [ValidationExceptionField]?
        public let message: String
        /// The reason for the validation exception.
        public let reason: ValidationExceptionReason?

        @inlinable
        public init(fields: [ValidationExceptionField]? = nil, message: String, reason: ValidationExceptionReason? = nil) {
            self.fields = fields
            self.message = message
            self.reason = reason
        }

        private enum CodingKeys: String, CodingKey {
            case fields = "fields"
            case message = "message"
            case reason = "reason"
        }
    }

    public struct ValidationExceptionField: AWSDecodableShape {
        /// The message of the exception field.
        public let message: String
        /// The name of the exception field.
        public let name: String

        @inlinable
        public init(message: String, name: String) {
            self.message = message
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case name = "name"
        }
    }
}

// MARK: - Errors

/// Error enum for GreengrassV2
public struct GreengrassV2ErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case conflictException = "ConflictException"
        case internalServerException = "InternalServerException"
        case requestAlreadyInProgressException = "RequestAlreadyInProgressException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case serviceQuotaExceededException = "ServiceQuotaExceededException"
        case throttlingException = "ThrottlingException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize GreengrassV2
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// You don't have permission to perform the action.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    /// Your request has conflicting operations. This can occur if you're trying to perform more than one operation on the same resource at the same time.
    public static var conflictException: Self { .init(.conflictException) }
    /// IoT Greengrass can't process your request right now. Try again later.
    public static var internalServerException: Self { .init(.internalServerException) }
    /// The request is already in progress. This exception occurs when you use a client token for multiple requests while IoT Greengrass is still processing an earlier request that uses the same client token.
    public static var requestAlreadyInProgressException: Self { .init(.requestAlreadyInProgressException) }
    /// The requested resource can't be found.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// Your request exceeds a service quota. For example, you might have the maximum number of components that you can create.
    public static var serviceQuotaExceededException: Self { .init(.serviceQuotaExceededException) }
    /// Your request exceeded a request rate quota. For example, you might have exceeded the amount of times that you can retrieve device or deployment status per second.
    public static var throttlingException: Self { .init(.throttlingException) }
    /// The request isn't valid. This can occur if your request contains malformed JSON or unsupported characters.
    public static var validationException: Self { .init(.validationException) }
}

extension GreengrassV2ErrorType: AWSServiceErrorType {
    public static let errorCodeMap: [String: AWSErrorShape.Type] = [
        "ConflictException": GreengrassV2.ConflictException.self,
        "InternalServerException": GreengrassV2.InternalServerException.self,
        "ResourceNotFoundException": GreengrassV2.ResourceNotFoundException.self,
        "ServiceQuotaExceededException": GreengrassV2.ServiceQuotaExceededException.self,
        "ThrottlingException": GreengrassV2.ThrottlingException.self,
        "ValidationException": GreengrassV2.ValidationException.self
    ]
}

extension GreengrassV2ErrorType: Equatable {
    public static func == (lhs: GreengrassV2ErrorType, rhs: GreengrassV2ErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension GreengrassV2ErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
